<?php
/**
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 3 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

namespace Util;

/**
 * Generates output for Programtech invoicing system
 * Works @ 2011.11.30
 * @package Util
 * @author Vincze Tamás pilou@pilou.hu
 * @version 0.1
 */
class Programtech
{
	/**
	 * Type of the invoice
	 * @var string SZÁLLÍTÓLEVÉL|SZÁMLA|DÍJBEKÉRŐ
	 */
	public $invoiceType;
	
	/**
	 * Required the name of the buyer
	 * @var string
	 */
	public $buyerName;
	
	/**
	 * Additional text below the name of the buyer
	 * @var string
	 */
	public $buyerNameMisc;
	
	/**
	 * Country of the buyer
	 * @var string
	 */
	public $buyerCountry = "Magyarország";
	
	/**
	 * Required the zip of the buyer
	 * @var string
	 */
	public $buyerZip;
	
	/**
	 * Required the zip of the buyer
	 * @var string
	 */
	public $buyerSettlement;
	
	/**
	 * Required the address of the buyer
	 * @var string
	 */
	public $buyerAddress;
	
	/**
	 * VAT number of the buyer
	 * @var string
	 */
	public $buyerVatNumber;
	
	/**
	 * The email of the buyer
	 * @var string
	 */
	public $buyerEmail;
	
	/**
	 * The phone of the buyer
	 * @var string
	 */
	public $buyerPhone;
	
	/**
	 * The fax of the buyer
	 * @var string
	 */
	public $buyerFax;
	
	/**
	 * @var string
	 */
	public $buyerContactName;
	
	/**
	 * @var string
	 */
	public $buyerPostName;
	
	/**
	 * @var string
	 */
	public $buyerPostZip;
	
	/**
	 * @var string
	 */
	public $buyerPostSettelement;
	
	/**
	 * @var string
	 */
	public $buyerPostAddress;
	
	/**
	 * @var string
	 */
	public $buyerBankAccountNumber;
	
	/**
	 * @var string
	 */
	public $buyerBankName;
	
	/**
	 * @var string
	 */
	public $buyerBankSWIFT;
	
	/**
	 * @var string
	 */
	public $buyerBankIBAN;
	
	/**
	 * Required
	 * @var string
	 */
	public $payMode;
	
	/**
	 * Required
	 * @var string Yyyy.mm.dd
	 */
	public $payDeadline;
	
	/**
	 * Required the currency
	 * @var string
	 */
	public $payCurrency;
	
	/**
	 * @var string
	 */
	public $bankAccountNumber;
	
	/**
	 * @var string
	 */
	public $bankName;
	
	/**
	 * @var string
	 */
	public $bankSWIFT;
	
	/**
	 * @var string
	 */
	public $bankIBAN;
	
	/**
	 * @var string
	 * @example IGEN|NEM
	 */
	public $printImmediately = "NEM";
	
	/**
	 * @var string 3 chars
	 * @example HUN|ENG|GER
	 */
	public $language = "HUN";
	
	/**
	 * @var string Yyyy.mm.dd
	 */
	public $completionDate;
	
	/**
	 *
	 * @var array
	 */
	protected $_products = array();
	
	/**
	 * @var string
	 */
	public $endText;
	
	/**
	 * @var float
	 */
	public $exchangeRate;
	
	/**
	 * Pattern to validate dates
	 * @var string
	 */
	protected $_datePattern = "!^[\d]{4}\.(0|1)[\d]\.(0|1|2|3)[\d]$!";

	
	/**
	 * Sets the required values for invoicing
	 * @param string $buyerName
	 * @param string $buyerZip
	 * @param string $buyerSettlement
	 * @param string $buyerAddress
	 * @param string $payMode
	 * @param string $payDeadline
	 * @param string $payCurrency
	 * @return void
	 */	
	public function __construct($buyerName, $buyerZip, $buyerSettlement, $buyerAddress, $payMode, $payDeadline, $payCurrency){
		$this->buyerName = $buyerName;
		$this->buyerZip = $buyerZip;
		$this->buyerSettlement = $buyerSettlement;
		$this->buyerAddress = $buyerAddress;
		
		$this->payMode = $payMode;
		$this->payDeadline = $payDeadline;
		$this->payCurrency = $payCurrency;
	}

	/**
	 * Sets the required values for invoicing
	 * @param string $buyerName
	 * @param string $buyerZip
	 * @param string $buyerSettlement
	 * @param string $buyerAddress
	 * @param string $payMode
	 * @param string $payDeadline
	 * @param string $payCurrency
	 * @return self 
	 */
	public static function init($buyerName, $buyerZip, $buyerSettlement, $buyerAddress, $payMode, $payDeadline, $payCurrency){
		return new self($buyerName, $buyerZip, $buyerSettlement, $buyerAddress, $payMode, $payDeadline, $payCurrency);
	}
	
	/**
	 *
	 * @param string $name
	 * @param string $TESZORnumber
	 * @param float $vat
	 * @param string $unit
	 * @param int $qty
	 * @param float $netPrice
	 * @param string $itemNumber
	 * @param string $comment 
	 */
	public function addProduct($name, $TESZORnumber, $vat, $unit, $qty, $netPrice, $itemNumber = null, $comment = null){
		$this->_products[] = array(
			"[_VTSZSZJ]" => substr($TESZORnumber, 0, 11),
			"[_MEGNEVEZES]" => substr($name, 0, 100),
			"[MEGJEGYZES]" => substr($comment, 0, 200),
			"[CIKKSZAM]" => substr($itemNumber, 0, 30),
			"[_AFAKULCS]" => substr((int) $vat, 0, 3),
			"[_MENNYISEG]" => $qty,
			"[_MERTEKEGYSEG]" => substr($unit, 0, 9),
			"[_EGYSEGARNETTO]" => $netPrice
		);
	}
	
	public function getOutput(){
		$this->validate();
		
		$output = array();
		$output[] = "[FILE_ELEJE]";
		if (!is_null($this->invoiceType)){
			$output[] = "[BIZONYLAT_TIPUSA]".$this->invoiceType;
		}
		$output[] = "[_VEVONEVE]".substr($this->buyerName, 0, 100);
		if (!is_null($this->buyerNameMisc)){
			$output[] = "[VEVONEVE_EGYEB]".substr($this->buyerNameMisc, 0, 100);
		}
		if (!is_null($this->buyerCountry)){
			$output[] = "[VEVOORSZAG]".substr($this->buyerCountry, 0, 30);
		}
		$output[] = "[_VEVOIRSZAM]".substr($this->buyerZip, 0, 15);
		$output[] = "[_VEVOTELEPULES]".substr($this->buyerSettlement, 0, 50);
		$output[] = "[_VEVOCIM]".substr($this->buyerAddress, 0, 50);
		if (!is_null($this->buyerVatNumber)){
			$output[] = "[VEVOADOSZAM]".substr($this->buyerVatNumber, 0, 30);
		}
		if (!is_null($this->buyerEmail)){
			$output[] = "[VEVOEMAIL]".substr($this->buyerEmail, 0, 60);
		}
		if (!is_null($this->buyerFax)){
			$output[] = "[VEVOFAX]".substr($this->buyerFax, 0, 20);
		}
		if (!is_null($this->buyerPhone)){
			$output[] = "[VEVOTEL]".substr($this->buyerPhone, 0, 20);
		}
		if (!is_null($this->buyerContactName)){
			$output[] = "[VEVOKAPCSOLATTARTO]".substr($this->buyerContactName, 0, 50);
		}
		if (!is_null($this->buyerPostName)){
			$output[] = "[VEVOPOSTANEV]".substr($this->buyerPostName, 0, 100);
		}
		if (!is_null($this->buyerPostZip)){
			$output[] = "[VEVOPOSTAIRSZAM]".substr($this->buyerPostZip, 0, 15);
		}
		if (!is_null($this->buyerPostSettelement)){
			$output[] = "[VEVOPOSTATELEPULES]".substr($this->buyerPostSettelement, 0, 50);
		}
		if (!is_null($this->buyerPostAddress)){
			$output[] = "[VEVOPOSTACIM]".substr($this->buyerPostAddress, 0, 50);
		}
		if (!is_null($this->buyerBankAccountNumber)){
			$output[] = "[VEVOBANKSZAMLASZAM]".substr($this->buyerBankAccountNumber, 0, 32);
		}
		if (!is_null($this->buyerBankName)){
			$output[] = "[VEVOBANKNEVECIME]".substr($this->buyerBankName, 0, 50);
		}
		if (!is_null($this->buyerBankSWIFT)){
			$output[] = "[VEVOBANKSWIFT]".substr($this->buyerBankSWIFT, 0, 50);
		}
		if (!is_null($this->buyerBankIBAN)){
			$output[] = "[VEVOBANKIBAN]".substr($this->buyerBankIBAN, 0, 50);
		}
		$output[] = "[_FIZETESIMODNEVE]".substr($this->payMode, 0, 15);
		$output[] = "[_FIZETESIHATARIDO]".$this->payDeadline;
		$output[] = "[_PENZNEM]".substr($this->payCurrency, 0, 3);
		if (!is_null($this->bankAccountNumber)){
			$output[] = "[BANK_SZAMLASZAM]".substr($this->bankAccountNumber, 0, 50);
		}
		if (!is_null($this->bankName)){
			$output[] = "[BANK_NEVE]".substr($this->bankName, 0, 50);
		}
		if (!is_null($this->bankIBAN)){
			$output[] = "[BANK_IBAN]".substr($this->buyerBankIBAN, 0, 50);
		}
		if (!is_null($this->bankSWIFT)){
			$output[] = "[BANK_SWIFT]".substr($this->bankSWIFT, 0, 50);
		}
		if (!is_null($this->printImmediately)){
			$output[] = "[NYOMTATAS_AZONNAL]".$this->printImmediately;
		}
		if (!is_null($this->language)){
			$output[] = "[NYELV]".substr($this->language, 0, 3);
		}
		if (!is_null($this->completionDate)){
			$output[] = "[TELJESITESDATUMA]".$this->completionDate;
		}
		
		$output[] = "[TERMEKEK_ELEJE]";
		foreach ($this->_products as $product) {
			$output[] = "[TERMEK]";
			foreach ($product as $key => $value) {
				$output[] = $key . $value;
			}
		}
		$output[] = "[TERMEKEK_VEGE]";
	
		if (!is_null($this->endText)){
			$output[] = "[BIZONYLATZARO_SZOVEG]".str_replace(array("[", "]"), array("(", ")"), $this->endText);
		}
		if (!is_null($this->exchangeRate)){
			$output[] = "[ARFOLYAM]".$this->exchangeRate;
		}
		$output[] = "[FILE_VEGE]";
		
		// be sure to catch the request with "hiv_szam" $_GET parameter
		return join("<br>", $output);
	}
	
	public function validate(){
		if (!is_null($this->invoiceType) && !in_array($this->invoiceType, array("SZÁLLÍTÓLEVÉL", "SZÁMLA", "DÍJBEKÉRŐ"))){
			throw new \Exception("invoiceType must be SZÁLLÍTÓLEVÉL or SZÁMLA or DÍJBEKÉRŐ");
		}
		if (!is_null($this->invoiceType) && !in_array($this->printImmediately, array("IGEN", "NEM"))){
			throw new \Exception("printImmediately must be IGEN, or NEM");
		}
		
		if (preg_match($this->_datePattern, $this->payDeadline) < 1){
			throw new \Exception("payDeadline syntax error. Right sysntax: Yyyy.mm.dd");
		}
		if (!is_null($this->completionDate) && preg_match($this->_datePattern, $this->completionDate)){
			throw new \Exception("completionDate syntax error. Right sysntax: Yyyy.mm.dd");
		}
	}
	
}
?>